#!/usr/local/bin/perl

package Armory::Char;
use strict;

use Armory::Item;
use LWP::UserAgent;
use XML::Simple;
use Data::Dumper;

sub new {
	my ($perlclass, %conf) = @_;
	my $self  = {};
	$self->{NAME}   = $conf{'name'} || undef;
	$self->{REALM}  = $conf{'realm'} || undef;
	bless($self, $perlclass);
	return $self;
}

sub updated {
	my $self = shift;
	return $self->{UPDATED};
}

sub name {
	my $self = shift;
	if (@_) { $self->{NAME} = shift }
	return $self->{NAME};
}

sub realm {
	my $self = shift;
	if (@_) { $self->{REALM} = shift }
	return $self->{REALM};
}

sub title {
	my $self = shift;
	return $self->{TITLE};
}

sub armor {
	my $self = shift;
	my $type = shift;
	$type = "effective" unless exists $self->{ARMOR}->{$type};
	return $self->{ARMOR}->{$type};
}

sub defense {
	my $self = shift;
	my $type = shift;
	$type = "value" unless exists $self->{DEFENSE}->{$type};
	return $self->{DEFENSE}->{$type};
}

sub dodge {
	my $self = shift;
	my $type = shift;
	$type = "percent" unless exists $self->{DODGE}->{$type};
	return $self->{DODGE}->{$type};
}

sub parry {
	my $self = shift;
	my $type = shift;
	$type = "percent" unless exists $self->{PARRY}->{$type};
	return $self->{PARRY}->{$type};
}

sub block {
	my $self = shift;
	my $type = shift;
	$type = "percent" unless exists $self->{BLOCK}->{$type};
	return $self->{BLOCK}->{$type};
}

sub resilience {
	my $self = shift;
	return $self->{RESILIENCE};
}

sub honkills {
	my $self = shift;
	return $self->{HONKILLS};
}

sub battlegroup {
	my $self = shift;
	return $self->{BATTLEGROUP};
}

sub level {
	my $self = shift;
	if (@_) { $self->{LEVEL} = shift }
	return $self->{LEVEL};
}

sub lastmod {
	my $self = shift;
	return $self->{LASTMOD};
}

sub guild {
	my $self = shift;
	return $self->{GUILD};
}

sub gender {
	my $self = shift;
	if (@_) { $self->{GENDER} = shift }
	return $self->{GENDER};
}

sub faction {
	my $self = shift;
	return $self->{FACTION};
}

sub health {
	my $self = shift;
	return $self->{HEALTH};
}

sub class {
	my $self = shift;
	if (@_) { $self->{CLASS} = shift }
	return $self->{CLASS};
}

sub race {
	my $self = shift;
	if (@_) { $self->{RACE} = shift }
	return $self->{RACE};
}

sub items {
	my $self = shift;
	return $self->{ITEMS};
}

sub reputations {
	my $self = shift;
	my $args = shift;
	if ($args) {
		if (exists($self->{FACTIONS}->{$args})) {
			return $self->{FACTIONS}->{$args};
		}
		else {
			return 0;
		}
	}
	else {
		return sort keys %{$self->{FACTIONS}};
	}
}

sub replevel {
	my $self = shift;
	my $level = shift;
	if ($level =~ /^-*\d+$/) {
		return "Hated" if ($level < -6000);
		return "Hostile" if ($level < -3000);
		return "Unfriendly" if ($level < 0);
		return "Neutral" if ($level < 3000);
		return "Friendly" if ($level < 9000);
		return "Honored" if ($level < 21000);
		return "Revered" if ($level < 42000);
		return "Exalted";
	} 
	else {
		return 0;
	}
}

sub skills {
	my $self = shift;
	my $skill = shift;
	my $arg = shift;
	if ($skill) {
		if ($self->{SKILLS}->{$skill}) {
			if ($arg eq "max") {
				return $self->{SKILLS}->{$skill}->{'max'};
			}
			else {
				return $self->{SKILLS}->{$skill}->{'value'};
			}
		}
		else {
			return 0;
		}
	} 
	else {
		return keys %{$self->{SKILLS}};
	}
}

sub fetch {
	my $self = shift;
	if (@_) { 
		my %conf = @_;
		$self->{NAME} = $conf{'name'} || $self->{NAME};
		$self->{REALM} = $conf{'realm'} || $self->{REALM};
	}

	my $ua = LWP::UserAgent->new( 'agent' => 'Firefox/2.0' );
	my $response = $ua->get('http://armory.worldofwarcraft.com/character-sheet.xml?r=' . $self->{REALM} . '&n=' . $self->{NAME});

	if (! $response->is_success) {
		return 0;
	}

	my $ref = XMLin($response->content);

	my $charinfo = $ref->{'characterInfo'}->{'character'};
	my $chartab = $ref->{'characterInfo'}->{'characterTab'};
	my $factions = $ref->{'characterInfo'}->{'reputationTab'}->{'factionCategory'};
	my $skilltab = $ref->{'characterInfo'}->{'skillTab'}->{'skillCategory'};;

	$self->{RACE} = $charinfo->{'race'};
	$self->{NAME} = $charinfo->{'name'};
	$self->{BATTLEGROUP} = $charinfo->{'battleGroup'};
	$self->{CLASS} = $charinfo->{'faction'};
	$self->{GENDER} = $charinfo->{'gender'};
	$self->{GUILD} = $charinfo->{'guildName'};
	$self->{GUILDURL} = $charinfo->{'guildUrl'};
	$self->{LASTMOD} = $charinfo->{'lastModified'};
	$self->{LEVEL} = $charinfo->{'level'};
	$self->{TITLE} = $charinfo->{'title'};

	# And that's all you get from a non-updated character
	
	if (! $self->{RACE}) {
		return 0;
	}

	if ($skilltab) {
		$self->{UPDATED} = 1;
	}
	else {
		$self->{UPDATED} = 0;
		return 1;
	}

	# Moving on...

	#### Defenses

	$self->{ARMOR} = $chartab->{'defenses'}->{'armor'};
	$self->{DODGE} = $chartab->{'defenses'}->{'dodge'};
	$self->{PARRY} = $chartab->{'defenses'}->{'parry'};
	$self->{BLOCK} = $chartab->{'defenses'}->{'block'};
	$self->{DEFENSE}->{'rating'} = $chartab->{'defenses'}->{'defense'}->{'rating'};
	$self->{DEFENSE}->{'value'} = $chartab->{'defenses'}->{'defense'}->{'plusDefense'} + $chartab->{'defenses'}->{'defense'}->{'value'};;
	$self->{RESILIENCE} = $chartab->{'defenses'}->{'resilience'}->{'value'};

	$self->{HONKILLS} = $chartab->{'pvp'}->{'lifetimehonorablekills'}->{'value'};

	#### Items

	$self->{ITEMS} = ();
	for my $itemkey (keys %{$chartab->{'items'}->{'item'}}) {
		my $item = Armory::Item->new('id' => $itemkey, 'realm' => $self->{REALM}, 'charname' => $self->{NAME});
		push @{$self->{ITEMS}}, $item;
	}

	#### Stats -- incomplete

	$self->{HEALTH} = $chartab->{'characterBars'}->{'health'}->{'effective'};

	foreach my $skillCat (keys %{$skilltab}) {
		foreach my $skillname (keys %{$skilltab->{$skillCat}->{'skill'}}) {
			$self->{SKILLS}->{$skillname} = 
				$skilltab->{$skillCat}->{'skill'}->{$skillname};;
		}
	}

	# Ugly workarounds for XML::Simple follow

	if (exists $factions->{'faction'}) {
		foreach my $factionname (keys %{$factions->{'faction'}}) {
			$self->{FACTIONS}->{$factionname} = 
				$factions->{faction}->{$factionname}->{'reputation'};

		}
	}
	else {
		foreach my $factionCat (keys %{$factions}) {
			if (exists $factions->{$factionCat}->{'faction'}->{'name'}) {
				my $factionname = $factions->{$factionCat}->{'faction'}->{'name'};
				$self->{FACTIONS}->{$factionname} =
					$factions->{$factionCat}->{'faction'}->{'reputation'};

			} 
			else {
				foreach my $factionname (keys %{$factions->{$factionCat}->{faction}}) {
					$self->{FACTIONS}->{$factionname} = 
						$factions->{$factionCat}->{faction}->{$factionname}->{'reputation'};
				}
			}
		}
	}

	return 1;
}

1;
